package com.linjm.gmalllist.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
import com.linjm.bean.SkuLsInfo;
import com.linjm.bean.SkuLsParams;
import com.linjm.bean.SkuLsResult;
import com.linjm.gmalllist.util.EsUtil;
import com.linjm.service.ListService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.dubbo.config.annotation.DubboService;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;

import org.elasticsearch.client.ml.job.results.Bucket;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import javax.naming.directory.SearchResult;
import javax.print.DocFlavor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@DubboService
@Service
public class ListServiceImpl implements ListService {

    @Qualifier("restHighLevelClient")
    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private EsUtil esUtil;

    public void saveSkuInfo(SkuLsInfo skuLsInfo) throws IOException {

        esUtil.addData((JSONObject) JSON.toJSON(skuLsInfo), "gmall", skuLsInfo.getId());
    }

    @Override
    public  SkuLsResult search(SkuLsParams skuLsParams) throws IOException {
        SearchRequest request = new SearchRequest("gmall");
        //定义一个查询器
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //创建一个bool
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //判断搜索关键字keyword是否为空
        if(skuLsParams.getKeyword()!=null){
            //创建match
            MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName",skuLsParams.getKeyword());
            //创建must并添加match
            boolQueryBuilder.must(matchQueryBuilder);
        }
        //判断三级分类ID是否存在
        if(skuLsParams.getCatalog3Id()!=null){
            //创建term
            TermQueryBuilder termQueryBuilder = new TermQueryBuilder("catalog3Id", skuLsParams.getCatalog3Id());
            //创建filler并添加term
            boolQueryBuilder.filter(termQueryBuilder);
        }
        if (skuLsParams.getValueId()!=null){
            for (String valueId : skuLsParams.getValueId()) {
                //创建term
                TermQueryBuilder termQueryBuilder = new TermQueryBuilder("skuAttrValueList.valueId", valueId);
                //创建filler并添加term
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }
        builder.query(boolQueryBuilder);
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("skuName");
        highlightBuilder.preTags("<span style=color:red>");
        highlightBuilder.postTags("</span>");
        builder.highlighter(highlightBuilder);
        //分页
        int from = skuLsParams.getPageNo()*skuLsParams.getPageSize();
        builder.from(from);
        builder.size(skuLsParams.getPageSize());
        //排序
        builder.sort("price", SortOrder.DESC);
        //创建一个聚合对象
        TermsAggregationBuilder groupby_attr = AggregationBuilders.terms("groupby_attr");
        groupby_attr.field("skuAttrValueList.valueId");
        builder.aggregation(groupby_attr);
        builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        request.source(builder);
        //解析结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        ArrayList<SkuLsInfo> skuLsInfoArrayList = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, HighlightField> high = hit.getHighlightFields();

            HighlightField skuName = high.get("skuName");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if (skuName!=null){
                Text[] texts = skuName.fragments();
                String nSkuName = "";
                for (Text text : texts) {
                    nSkuName+=text;
                }
                //替换
                sourceAsMap.put("skuName", nSkuName);
            }
            SkuLsInfo skuLsInfo = JSON.parseObject(JSON.toJSONString(sourceAsMap), SkuLsInfo.class);
            skuLsInfoArrayList.add(skuLsInfo);

        }

        SkuLsResult skuLsResult = new SkuLsResult();
        skuLsResult.setSkuLsInfoList(skuLsInfoArrayList);
        long value = response.getHits().getTotalHits().value;
        skuLsResult.setTotal(value);
        //计算总页数
        long totalPages=(value+skuLsParams.getPageSize()-1)/skuLsParams.getPageSize();
        skuLsResult.setTotalPages(totalPages);
        // 声明一个集合来存储平台属性值Id
        ArrayList<String> stringArrayList = new ArrayList<>();
        // 获取平台属性值Id
        Aggregations aggregations = response.getAggregations();
        Terms attr  = aggregations.get("groupby_attr");
        List<? extends Terms.Bucket> buckets = attr.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            String valueId = (String) bucket.getKey();
            stringArrayList.add(valueId);
        }
        skuLsResult.setAttrValueIdList(stringArrayList);
        return skuLsResult;
    }


}
